import store from "../store";
import { createDiscreteApi } from "naive-ui";
const $Message = createDiscreteApi(["message"]).message;
import $bus from "@/utils/bus";
import { localStorageSet } from "@/utils";

let websocket = null; // 用于存储实例化后websocket
let rec; // 断线重连后，延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码
let heartbeatInterval;

// 创建websocket
function creatWebSocket(wsUrl) {
  // 判断当前浏览器是否支持WebSocket
  if ("WebSocket" in window) {
    console.log("当前浏览器支持 WebSocket");
  } else if ("MozWebSocket" in window) {
    console.log("当前浏览器支持 MozWebSocket");
  } else {
    console.log("当前浏览器不支持 WebSocket");
  }

  try {
    initWebSocket(wsUrl); // 初始化websocket连接
  } catch (e) {
    console.log("尝试创建连接失败");
    reConnect(wsUrl); // 如果无法连接上 webSocket 那么重新连接！可能会因为服务器重新部署，或者短暂断网等导致无法创建连接
  }
}

// 初始化websocket
function initWebSocket(wsUrl) {
  // closeWebSocket
  if (websocket) closeWebSocket()
  websocket = new WebSocket(wsUrl);
  // console.log("websocket:", websocket);
  websocket.onopen = function () {
    store.commit("SET_IS_CONNECTED", true);
    websocketOpen();
  };

  //   // 接收
  websocket.onmessage = function (e) {
    websocketonmessage(e);
  };

  // 连接发生错误
  websocket.onerror = function () {
    console.log("websocket.onerror => WebSocket连接发生错误");
    store.commit("SET_IS_CONNECTED", false);
  };

  websocket.onclose = function (e) {
    websocketclose(e);
  };
}

// 定义重连函数
function reConnect(wsUrl) {
  console.log("尝试重新连接 => ", wsUrl);
  if (store.getters.isConnected) {
    clearTimeout(rec);
    return; // 如果已经连上就不在重连了
  }
  creatWebSocket(wsUrl);
  rec && clearTimeout(rec);
  rec = setTimeout(function () {
    // 延迟3秒重连  避免过多次过频繁请求重连
    reConnect(wsUrl);
  }, 3000);
}

// 心跳
function sendHeartbeat(type = 1) {
  websocketsend(type == 1 ? {
    "action" : 0,
    "data" : "{\"heartBeatMsg\" : \"heart beating!\"}"
  } : {
    "action" : 0,
    "data" : "{\"heartBeatMsg\" : \"PONG heart beating!\"}"
  });
}

// 创建连接
function websocketOpen() {
  // console.log("连接成功");
  store.dispatch("CONNECT"); // 修改连接状态
  // 发送心跳
  heartbeatInterval = setInterval(() => sendHeartbeat(1), 30000)
}
// 数据接收
function websocketonmessage(e) {
  // console.log("数据接收 => ", JSON.parse(e.data));
  const data = JSON.parse(e.data); // 解析JSON格式的数据
  // 下面的判断则是后台返回的接收到的数据  如何处理自己决定
  switch (data.code) {
    case 400:
    case 404:
      $Message.warning(data.msg);
      break;
    case 0:
      if (
        data.action == 0 && 
        data.data
      ) {
        // 心跳
        if (JSON.parse(data.data) === "PING heart beating!") {
          sendHeartbeat(2);
        }
      } else if(
        data.action == 2 && 
        data.data
      ) {
        $bus.$emit("socketMsg", data);
      } else if(
        data.action == 5 && 
        data.data
      ) {
        // 缓存 clientChannelInfo 数据
        // clientChannelHost, clientChannelId
        let imClientChannelInfo = JSON.parse(data.data);
        localStorageSet("imClientChannelInfo", JSON.stringify(imClientChannelInfo));
      }
      if (
        data.id
      ) {
        $bus.$emit("msgStatusUp", data);
      }
      break;
    case 200:
      $Message.success(data.msg);
      break;
    default:
      $Message.error(data.msg);
      // 延时5秒后刷新页面
      // setTimeout(() => { location.reload() }, 1000);
      break;
  }

  // let data = JSON.parse(decodeUnicode(e.data))
}

// 关闭
function websocketclose(e) {
  console.log(e);
  store.dispatch("DISCONNECT"); // 修改连接状态
  clearInterval(heartbeatInterval);
  // console.log("connection closed (" + e.code + ")");
}

// 数据发送
function websocketsend(data) {
  // console.log("发送的数据", data, JSON.stringify(data));
  // 检查连接状态
  if (websocket && store.getters.isConnected) {
    websocket.send(JSON.stringify(data));
  } else {
    store.commit("SET_IS_CONNECTED", false);
    // $Message.error("Connection error, please refresh the page");
    $Message.error("Connection error, please retry later.");
    $bus.$emit("msgSockReConnect");
  }
}


// 关闭
let closeWebSocket = () => {
  if (websocket) {
    websocket.close();
    // $Message.success("设备已关闭");
  }
};

export { initWebSocket, reConnect, creatWebSocket, closeWebSocket, websocketsend };
